package win.larryzeal.jmx;

/**
 * Created by 张少昆 on 2017/8/18 0018.
 */

import win.larryzeal.jmx.mbean.standard.HelloMBean;

import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;

/**
 * 在HelloAgent启动之后，通过RMI连接到MBeanServer，获取MBean，并对其进行操作。
 */
public class RMIClient4MBeanServer {

	public static void main(String[] args) throws IOException,
			MalformedObjectNameException, InstanceNotFoundException,
			AttributeNotFoundException, InvalidAttributeValueException,
			MBeanException, ReflectionException, IntrospectionException{

		String domainName = "my_domain_name";
		int rmiPort = 1099;
		JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + rmiPort + "/" + domainName);
		// 可以连接HelloAgent.java中的那句：
		// JMXConnectorServer jmxConnector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
		JMXConnector jmxConnector = JMXConnectorFactory.connect(url);//Creates a connection to the connector server at the given address.
		MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();

		//print domains
		System.out.println("Domains:------------------");
		String domains[] = mBeanServerConnection.getDomains();
		for(int i = 0; i < domains.length; i++){
			System.out.println("\tDomain[" + i + "] = " + domains[i]);
		}
		//MBean count
		System.out.println("MBean count = " + mBeanServerConnection.getMBeanCount());
		//process attribute
		ObjectName mBeanName = new ObjectName(domainName + ":name=HelloWorld");
		mBeanServerConnection.setAttribute(mBeanName, new Attribute("Name", "ZZZZZZZ"));//TODO 注意这里是Name而不是name
		System.out.println("Name = " + mBeanServerConnection.getAttribute(mBeanName, "Name"));

		//接下去是执行Hello中的printHello方法，分别通过代理和rmi的方式执行
		//via proxy
		HelloMBean proxy = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection, mBeanName, HelloMBean.class, false);
		proxy.printHello();
		proxy.printHello("机智 boy");
		//via rmi
		mBeanServerConnection.invoke(mBeanName, "printHello", null, null);
		mBeanServerConnection.invoke(mBeanName, "printHello", new String[]{"机智 gril"}, new String[]{String.class.getName()});

		//get mbean information
		MBeanInfo info = mBeanServerConnection.getMBeanInfo(mBeanName);
		System.out.println("Hello Class: " + info.getClassName());
		for(int i = 0; i < info.getAttributes().length; i++){
			System.out.println("Hello Attribute:" + info.getAttributes()[i].getName());
		}
		for(int i = 0; i < info.getOperations().length; i++){
			System.out.println("Hello Operation:" + info.getOperations()[i].getName());
		}

		//ObjectName of MBean
		System.out.println("all ObjectName:--------------");
		Set<ObjectInstance> set = mBeanServerConnection.queryMBeans(null, null);
		for(Iterator<ObjectInstance> it = set.iterator(); it.hasNext(); ){
			ObjectInstance oi = it.next();
			System.out.println("\t" + oi.getObjectName());
		}
		jmxConnector.close();
	}
}
